package com.agan.jvm.controller;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
/**
 * @author 阿甘
 * @see https://study.163.com/course/introduction/1211562809.htm?share=1&shareId=1028852228
 * @version 1.0
 * 注：如有任何疑问,欢迎加阿甘老师微信agan-java 进行讨论
 */
@RestController
public class GCController {


    @GetMapping(value = "/gc")
    public  void gc() throws InterruptedException {
        List<Object> tmpList2 = new ArrayList<>();
        while(true) {
            for (int i = 0; i < 10; i++) {
                //tmpList1用于模拟生产环境中一些存活周期比较长，能晋升到老年代
                //而且能被mixed gc回收的对象
                List<Object> tmpList1 = new ArrayList<>();
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());
                tmpList1.add(new _1M());

                //tmpList2用于模拟生产环境中那些因为bug导致的不能被回收的对象
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                tmpList2.add(new _2M());
                 /*
                 每次循环，都会有30M的对象进入新生代，这些对象用于触发Young GC,
                 不考虑大对象直接进入老年代、空间分配担保和对象晋升年龄动态判断
                 等因素，15次Young GC之后，tmpList1和tmpList2会晋升到老年代。
                 这个循环用
                 */
                for (int j = 0; j < 1000; j++) {
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
                    new _1M();
                    new _2M();
//                    Thread.sleep(2);
                }
                //释放tmpList1的强引用，让G1有机会回收
                tmpList1 = null;
//                tmpList2=null;
            }
        }
    }


    private static class _1M{
        private byte[] bytes = new byte[1024*1024];
    }

    private static class _2M {
        private byte[] bytes = new byte[2*1024*1024];
    }


}












